#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <semaphore.h>
#include <pthread.h>


void *jogar_pontos1(void*);
void *jogar_pontos2(void*);
void *jogar_pontos3(void*);
void *jogar_pontos4(void*);
pthread_t th_1, th_2, th_3, th_4;
sem_t sem_1, sem_2, th1, th2, th3, th4;

unsigned long int pointsIn = 0;
unsigned long int pointsTotal = 0;
float PI;
time_t inicio;

int main(int argc, char *argv[])
{

    srand((unsigned)time(NULL));
    
	sem_init(&sem_1, 0, 1);
	sem_init(&sem_2, 0, 1);
	sem_init(&th1, 0, 0);
	sem_init(&th2, 0, 0);
	sem_init(&th3, 0, 0);
	sem_init(&th4, 0, 0);

    inicio = time(0);
    
        pthread_create(&th_1, NULL, jogar_pontos1, NULL);
        pthread_create(&th_2, NULL, jogar_pontos2, NULL);
      	pthread_create(&th_3, NULL, jogar_pontos3, NULL);
        pthread_create(&th_4, NULL, jogar_pontos4, NULL);
    sem_wait(&th1);
    sem_wait(&th2);	
    sem_wait(&th3);
    sem_wait(&th4);
    
    
    PI = (float)4*pointsIn/pointsTotal;
                            // PI = pointsIn/pointsTotal
    
    printf("Tempo: %d\n", time(0)-inicio);
    printf("%d %d\n", pointsIn, pointsTotal);
    printf("PI = %.20f\n", PI);    
    
   	sem_destroy(&sem_1);
	sem_destroy(&sem_2);
	sem_destroy(&th1);
	sem_destroy(&th2);
	sem_destroy(&th3);
	sem_destroy(&th4);
   	
	return 0;
    
}

void *jogar_pontos1(void *arg)
{
     
     float px, py, aux, aux2;
     int i;
     
     for (i = 0; i <= 12500000; i++)
     {
      px = 2;
      py = 2;     
      while ((px<0) || (px>1))
           px = (float)rand()/rand();
      while ((py<0) || (py>1))
           py = (float)rand()/rand();

      sem_wait(&sem_1);
      pointsTotal++;
      sem_post(&sem_1);
          
      px = px*px;
      py = py*py;
          
      aux = px + py;

      aux2 = sqrt(aux);

      if ( aux2 <= 1 )
      {
        sem_wait(&sem_2);  
        pointsIn++;
        sem_post(&sem_2);
      }
     }
     
     sem_post(&th1);
     
     return NULL;
}

void *jogar_pontos2(void *arg)
{
     
     float px, py, aux, aux2;
     int i;
     
     for (i = 0; i <= 12500000; i++)
     {
      px = 2;
      py = 2;     
      while ((px<0) || (px>1))
           px = (float)rand()/rand();
      while ((py<0) || (py>1))
           py = (float)rand()/rand();

      sem_wait(&sem_1);
      pointsTotal++;
      sem_post(&sem_1);
          
      px = px*px;
      py = py*py;
          
      aux = px + py;

      aux2 = sqrt(aux);

      if ( aux2 <= 1 )
      {
        sem_wait(&sem_2);  
        pointsIn++;
        sem_post(&sem_2);
      }
     }
     
     sem_post(&th2);
     
     return NULL;
}

void *jogar_pontos3(void *arg)
{
     
     float px, py, aux, aux2;
     int i;
     
     for (i = 0; i <= 12500000; i++)
     {
      px = 2;
      py = 2;     
      while ((px<0) || (px>1))
           px = (float)rand()/rand();
      while ((py<0) || (py>1))
           py = (float)rand()/rand();

      sem_wait(&sem_1);
      pointsTotal++;
      sem_post(&sem_1);
          
      px = px*px;
      py = py*py;
          
      aux = px + py;

      aux2 = sqrt(aux);

      if ( aux2 <= 1 )
      {
        sem_wait(&sem_2);  
        pointsIn++;
        sem_post(&sem_2);
      }
     }
     
     sem_post(&th3);
     
     return NULL;
}

void *jogar_pontos4(void *arg)
{
     
     float px, py, aux, aux2;
     int i;
     
     for (i = 0; i <= 12500000; i++)
     {
      px = 2;
      py = 2;     
      while ((px<0) || (px>1))
           px = (float)rand()/rand();
      while ((py<0) || (py>1))
           py = (float)rand()/rand();

      sem_wait(&sem_1);
      pointsTotal++;
      sem_post(&sem_1);
          
      px = px*px;
      py = py*py;
          
      aux = px + py;

      aux2 = sqrt(aux);

      if ( aux2 <= 1 )
      {
        sem_wait(&sem_2);  
        pointsIn++;
        sem_post(&sem_2);
      }
     }
     
     sem_post(&th4);
     
     return NULL;
}
